module Controller(opcode, funct, RegDst, Branch, MemtoReg, AluSrc, AluOp, MemWrite, RegWrite, Jump,Sign);

    input   [5:0] opcode;   
    input   [5:0]   funct ;   

    output          RegDst;   
    output          Branch;   
    output          MemtoReg; 
    output          AluSrc;   
    output   [3:0]  AluOp;    
    output          MemWrite; 
    output          RegWrite; 
    output          Jump;     
    output          Sign;
    
    //OPCODE
    parameter   RTYPE = 6'b000000;               
    parameter   ADDI  = 6'b001000;               
    parameter   ADDIU = 6'b001001;               
    parameter   BEQ   = 6'b000100;               
    parameter   J     = 6'b000010;               
    parameter   LW    = 6'b100011;               
    parameter   SW    = 6'b101011;               
    parameter   LUI   = 6'b001111;               
    parameter   ORI   = 6'b001101;

    //OUTPUT
    parameter   RT = 1'b1, RD = 1'b0;                           // RegDst
    parameter   BRANCH = 1'b1, NOBRANCH = 1'b0;                 // Branch
    parameter   DMOUT = 1'b1, ALURESULT = 1'b0;                 // MemtoReg
    parameter   RD2 = 1'b1, IMMEDIATE_NUMBER = 1'b0;            // AluSrc
    parameter   SL_ALUOP = 4'b0000, BR_ALUOP = 4'b0001, AL_ALUOP = 4'b0010, LU_ALUOP = 4'b0011,ADDI_ALUOP=4'b0100,ORI_ALUOP=4'b0101; // AlluOp {store or load,branch,Arithmetic logic,lui} 
    parameter   MEMWRITE = 1'b1, NOMEMWRITE = 1'b0;             // MemWrite
    parameter   REGWRITE = 1'b1, NOREGWRITE = 1'b0;             // RegWrite
    parameter   JUMP = 1'b1, NOJUMP = 1'b0;                     // Jump
    parameter   SIGN=1'b1,UNSIGN=1'b0;

    reg   [11:0] controls;
                 
    assign {RegDst, Branch, MemtoReg, AluSrc, AluOp, MemWrite, RegWrite, Jump,Sign} = controls;

    always @(*)
    begin
       case(opcode)
            RTYPE:                                  // R type
            begin
                controls = {RD, NOBRANCH, ALURESULT, RD2, AL_ALUOP, NOMEMWRITE, REGWRITE, NOJUMP,SIGN};       
            end
            ADDI : controls <= {RT, NOBRANCH, ALURESULT, IMMEDIATE_NUMBER, ADDI_ALUOP, NOMEMWRITE, REGWRITE, NOJUMP,SIGN}; 
            ADDIU: controls <= {RT, NOBRANCH, ALURESULT, IMMEDIATE_NUMBER, ADDI_ALUOP, NOMEMWRITE, REGWRITE, NOJUMP,SIGN}; 
            ORI  :controls <= {RT, NOBRANCH, ALURESULT, IMMEDIATE_NUMBER, ORI_ALUOP, NOMEMWRITE, REGWRITE, NOJUMP,SIGN}; 
            BEQ  : controls <= {RT, BRANCH, ALURESULT, RD2, BR_ALUOP, NOMEMWRITE, NOREGWRITE, NOJUMP,SIGN}; 
            J    : controls <= {RT, NOBRANCH, ALURESULT, IMMEDIATE_NUMBER, SL_ALUOP, NOMEMWRITE, NOREGWRITE, JUMP,SIGN}; 
            LW   : controls <= {RT, NOBRANCH, DMOUT, IMMEDIATE_NUMBER, SL_ALUOP, NOMEMWRITE, REGWRITE, NOJUMP,SIGN}; 
            SW   : controls <= {RT, NOBRANCH, DMOUT, IMMEDIATE_NUMBER, SL_ALUOP, MEMWRITE, NOREGWRITE, NOJUMP,SIGN}; 
            LUI  :controls <= {RT, NOBRANCH, ALURESULT, IMMEDIATE_NUMBER, LU_ALUOP, NOMEMWRITE, REGWRITE, NOJUMP,SIGN}; 

            default: controls <= 9'bxxxxxxxxx; 
       endcase
    end
       
endmodule